package com.shenda.security;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

import com.shenda.starter.config.Config;
import com.shenda.starter.config.Settings;
import com.swak.OS;
import com.swak.entity.Result;
import com.swak.exception.ErrorCode;
import com.swak.utils.StringUtils;
import com.swak.vertx.security.handler.AdviceHandler;
import com.swak.vertx.transport.HttpConst;
import com.swak.vertx.transport.Subject;

import io.netty.handler.codec.http.HttpHeaderNames;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.ext.web.RoutingContext;

/**
 * Api 访问权限控制
 * 
 * @author lifeng
 */
public class RolesxHandler extends AdviceHandler {

	private final String ip;

	public RolesxHandler() {
		this.ip = OS.ip();
	}

	/**
	 * 权限判断
	 */
	@Override
	public CompletionStage<Boolean> isAccessDenied(RoutingContext context, Subject subject) {
		return CompletableFuture.completedFuture(this.roleAllowed(context.request()));
	}
	
    /**
     * 如果不继续执行则怎么处理
     */
    @Override
    public CompletableFuture<Boolean> onAccessDenied(RoutingContext context, Subject subject) {
        context.response().putHeader(HttpHeaderNames.CONTENT_TYPE, HttpConst.APPLICATION_JSON);
        context.response().end(Result.error(ErrorCode.ACCESS_DENIED).toJson());
        return CompletableFuture.completedFuture(false);
    }

	/**
	 * 判断是否允许访问
	 * 
	 * @param request
	 * @return
	 */
	private boolean roleAllowed(HttpServerRequest request) {
		Config settings = Settings.me().getConfig();
		String ip = this.getRemoteAddr(request);
		if (isLocal(ip) || (settings.accessAble() && contains(Settings.me().getConfig().getAccessIps(), ip))) {
			return true;
		}
		return false;
	}

	/**
	 * 获得用户远程地址
	 */
	private String getRemoteAddr(HttpServerRequest request) {
		String remoteAddr = request.getHeader("X-Real-IP");
		if (StringUtils.isBlank(remoteAddr)) {
			remoteAddr = request.getHeader("X-Forwarded-For");
		} else if (StringUtils.isBlank(remoteAddr)) {
			remoteAddr = request.getHeader("Proxy-Client-IP");
		} else if (StringUtils.isBlank(remoteAddr)) {
			remoteAddr = request.getHeader("WL-Proxy-Client-IP");
		}
		return remoteAddr != null ? remoteAddr
				: (request.remoteAddress() != null ? request.remoteAddress().host() : null);
	}

	/**
	 * 是否包含设置的ip
	 * 
	 * @param ips
	 * @param ip
	 * @return
	 */
	private boolean contains(String ips, String ip) {
		if (ips != null) {
			return ips.indexOf(ip) != -1;
		}
		return false;
	}

	/**
	 * 是否本机请求
	 * 
	 * @param ip
	 * @return
	 */
	private boolean isLocal(String ip) {
		if (this.ip.equals(ip) || "127.0.0.1".equals(ip)) {
			return true;
		}
		return false;
	}
}